﻿using System;
using NTypeClasses;

namespace TypeClassSample.Monad
{
	[TypeClass]
	public abstract class Monad<
		[Typar(0, 2)] GenA,
		[Typar(0, 3)] GenB, A, B>
	{
		public abstract GenA Return(A a);
		public abstract GenB Bind(GenA a, Func<A, GenB> func);
		public abstract void FakeMethod(GenA a);
	}

	public static class MonadClass
	{
		public static GenA Return<GenA, A>(A a)
		{
			return TypeClass<Monad<GenA, AnyClass, A, AnyClass>>.Instance.Return(a);
		}

		public static GenB Bind<GenA, GenB, A>(GenA a, Func<A, GenB> func)
		{
			return TypeClass<Monad<GenA, GenB, A, AnyClass>>.Instance.Bind(a, func);
		}
	}
}
